# Redis缓存配置
import redis
from django.conf import settings
from django.core.cache import cache
from django.core.cache.backends.redis import RedisCache
import logging

logger = logging.getLogger(__name__)


class CacheManager:
    """缓存管理器"""
    
    # 缓存键前缀
    CACHE_PREFIXES = {
        'dashboard': 'dashboard_',
        'analytics': 'analytics_',
        'asset': 'asset_',
        'user': 'user_',
        'report': 'report_',
        'search': 'search_'
    }
    
    # 缓存超时时间（秒）
    CACHE_TIMEOUTS = {
        'dashboard_stats': 300,      # 5分钟
        'analytics_data': 600,       # 10分钟
        'asset_list': 180,           # 3分钟
        'user_permissions': 1800,    # 30分钟
        'report_data': 900,          # 15分钟
        'search_results': 120        # 2分钟
    }
    
    @classmethod
    def get_cache_key(cls, prefix, identifier):
        """生成缓存键"""
        if prefix not in cls.CACHE_PREFIXES:
            raise ValueError(f"未知的缓存前缀: {prefix}")
        return f"{cls.CACHE_PREFIXES[prefix]}{identifier}"
    
    @classmethod
    def set_cache(cls, prefix, identifier, data, timeout=None):
        """设置缓存"""
        cache_key = cls.get_cache_key(prefix, identifier)
        
        if timeout is None:
            # 根据前缀确定默认超时时间
            for key, default_timeout in cls.CACHE_TIMEOUTS.items():
                if key.startswith(prefix):
                    timeout = default_timeout
                    break
            else:
                timeout = 300  # 默认5分钟
        
        try:
            cache.set(cache_key, data, timeout)
            logger.debug(f"缓存设置成功: {cache_key}, 超时: {timeout}秒")
            return True
        except Exception as e:
            logger.error(f"缓存设置失败: {cache_key}, 错误: {e}")
            return False
    
    @classmethod
    def get_cache(cls, prefix, identifier):
        """获取缓存"""
        cache_key = cls.get_cache_key(prefix, identifier)
        
        try:
            data = cache.get(cache_key)
            if data is not None:
                logger.debug(f"缓存命中: {cache_key}")
            else:
                logger.debug(f"缓存未命中: {cache_key}")
            return data
        except Exception as e:
            logger.error(f"缓存获取失败: {cache_key}, 错误: {e}")
            return None
    
    @classmethod
    def delete_cache(cls, prefix, identifier=None):
        """删除缓存"""
        if identifier:
            cache_key = cls.get_cache_key(prefix, identifier)
            try:
                cache.delete(cache_key)
                logger.debug(f"缓存删除成功: {cache_key}")
                return True
            except Exception as e:
                logger.error(f"缓存删除失败: {cache_key}, 错误: {e}")
                return False
        else:
            # 删除所有相关前缀的缓存
            return cls.clear_prefix_cache(prefix)
    
    @classmethod
    def clear_prefix_cache(cls, prefix):
        """清除指定前缀的所有缓存"""
        try:
            if hasattr(cache, '_cache') and hasattr(cache._cache, '_cache'):
                # Redis缓存后端
                redis_client = cache._cache._cache
                pattern = f"{cls.CACHE_PREFIXES[prefix]}*"
                keys = redis_client.keys(pattern)
                if keys:
                    redis_client.delete(*keys)
                    logger.info(f"清除缓存成功: {len(keys)} 个键，前缀: {prefix}")
                return True
            else:
                # 其他缓存后端，使用Django的缓存清理
                cache.clear()
                logger.info(f"清除所有缓存成功")
                return True
        except Exception as e:
            logger.error(f"清除缓存失败，前缀: {prefix}, 错误: {e}")
            return False
    
    @classmethod
    def get_cache_stats(cls):
        """获取缓存统计信息"""
        try:
            if hasattr(cache, '_cache') and hasattr(cache._cache, '_cache'):
                redis_client = cache._cache._cache
                info = redis_client.info()
                
                stats = {
                    'redis_version': info.get('redis_version'),
                    'used_memory': info.get('used_memory_human'),
                    'connected_clients': info.get('connected_clients'),
                    'total_commands_processed': info.get('total_commands_processed'),
                    'keyspace_hits': info.get('keyspace_hits', 0),
                    'keyspace_misses': info.get('keyspace_misses', 0),
                    'hit_rate': 0
                }
                
                # 计算命中率
                hits = stats['keyspace_hits']
                misses = stats['keyspace_misses']
                if hits + misses > 0:
                    stats['hit_rate'] = round((hits / (hits + misses)) * 100, 2)
                
                return stats
            else:
                return {'message': '非Redis缓存后端，无法获取详细统计'}
        except Exception as e:
            logger.error(f"获取缓存统计失败: {e}")
            return {'error': str(e)}


class CacheDecorator:
    """缓存装饰器"""
    
    @staticmethod
    def cache_result(prefix, timeout=300, key_func=None):
        """结果缓存装饰器"""
        def decorator(func):
            def wrapper(*args, **kwargs):
                # 生成缓存键
                if key_func:
                    cache_key = key_func(*args, **kwargs)
                else:
                    # 使用函数名和参数生成键
                    key_parts = [func.__name__]
                    key_parts.extend([str(arg) for arg in args])
                    key_parts.extend([f"{k}_{v}" for k, v in sorted(kwargs.items())])
                    cache_key = "_".join(key_parts)
                
                # 尝试从缓存获取
                cached_result = CacheManager.get_cache(prefix, cache_key)
                if cached_result is not None:
                    return cached_result
                
                # 执行函数并缓存结果
                result = func(*args, **kwargs)
                CacheManager.set_cache(prefix, cache_key, result, timeout)
                
                return result
            return wrapper
        return decorator


# 缓存配置检查
def check_cache_config():
    """检查缓存配置"""
    try:
        # 测试缓存连接
        test_key = "cache_test"
        test_value = "test_data"
        
        cache.set(test_key, test_value, 10)
        retrieved_value = cache.get(test_key)
        
        if retrieved_value == test_value:
            cache.delete(test_key)
            logger.info("缓存配置检查通过")
            return True
        else:
            logger.error("缓存配置检查失败：数据不匹配")
            return False
    except Exception as e:
        logger.error(f"缓存配置检查失败: {e}")
        return False


# Redis连接池配置
def get_redis_connection():
    """获取Redis连接"""
    try:
        redis_settings = getattr(settings, 'CACHES', {}).get('default', {})
        if redis_settings.get('BACKEND') == 'django_redis.cache.RedisCache':
            location = redis_settings.get('LOCATION', 'redis://127.0.0.1:6379/1')
            return redis.from_url(location)
        else:
            logger.warning("未配置Redis缓存后端")
            return None
    except Exception as e:
        logger.error(f"获取Redis连接失败: {e}")
        return None
